﻿namespace Dissemination.MVC.Controllers
{
    using System.Web.Mvc;
    using Dissemination.MVC.Repositories;
    using Dissemination.MVC.ViewModels;
    using Dissemination.MVC.Models;
    using System;
    using System.Linq;
    using Extensions;
    using System.Collections.Generic;

    [HandleError]
    public class TestResultController : ControllerBase
    {
        protected TestResultRepository repository = new TestResultRepository();

        //#region List

        ////
        //// GET: /TestResult/

        /// <summary>
        /// Returns the view associated to the list of entities in the data source.
        /// </summary>
        /// <param name="seminarID"></param>
        /// <returns>Index view</returns>
        [Authorize(Roles = "Demostrator,Administrator,Reporter")]
        public ActionResult Index(int seminarID)
        {
            if (log.IsDebugEnabled) log.Debug("Entering TestResults list...");
            if (log.IsDebugEnabled) log.Debug("Leaving TestResults list...");
            var viewModel = new TestResultListViewModel
            {
                TestResults = repository.ListBySeminarID(seminarID),
                ParticipantsCount = repository.GetSeminarByID(seminarID).Participants.Count
            };

            return View(viewModel);
        }

        //#endregion

        #region Details

        //
        // GET: /TestResult/Details/5

        /// <summary>
        /// Returns the view associated to the details of an entity in the data source.
        /// </summary>
        /// <param name="id">The entity id.</param>
        /// <returns>Details view</returns>
        [Authorize(Roles = "Demostrator,Administrator,Reporter")]
        public ActionResult Details(int id)
        {
            if (log.IsDebugEnabled) log.DebugFormat("Entering TestResult details with id={0}...", id);
            TestResult testResult = repository.Get(id);

            if (testResult == null)
            {
                if (log.IsErrorEnabled) log.ErrorFormat("TestResult with id={0} not found", id);
                return View("NotFound");
            }

            if (log.IsDebugEnabled) log.DebugFormat("Leaving TestResult details with id={0}...", id);
            return View(testResult);
        }

        #endregion

        #region New

        //
        // GET: /TestResult/Create

        /// <summary>
        /// Returns the view associated with an empty entity
        /// </summary>
        /// <param name="seminarID"></param>
        /// <returns>Create view</returns>
        [Authorize(Roles = "Administrator,Reporter")]
        public ActionResult Create(int seminarID)
        {
            if (log.IsDebugEnabled) log.Debug("Entering TestResult creation (GET)...");
            Seminar seminar = repository.GetSeminarByID(seminarID);
            
            if (seminar.Participants.Count <= seminar.TestResults.Count)
            {
                ApplicationException exception = new ApplicationException(string.Format("The number of test results has reached the number of participants: ({0})", seminar.Participants.Count));
                if (log.IsErrorEnabled) log.Error(exception);
                return View("Error", exception);
            }

            TestResult testResult = new TestResult();

            if (log.IsDebugEnabled) log.Debug("Leaving TestResult creation (GET)..."); 
            return View(testResult);
        } 

        //
        // POST: /TestResult/Create

        /// <summary>
        /// Creates the specified entity.
        /// </summary>
        /// <param name="testResult">The entity</param>
        /// <returns>Details view</returns>
        [HttpPost]
        [Authorize(Roles = "Administrator,Reporter")]
        public ActionResult Create(TestResult testResult)
        {
            if (log.IsDebugEnabled) log.Debug("Entering TestResult creation (POST)...");
            if (ModelState.IsValid)
            {

                try
                {
                    if (testResult.TestResultTotalAnswers > 20)
                    {
                        ApplicationException exception = new ApplicationException("The total of <em>correct</em>, <em>incorrect</em> and <em>not answered</em> questions must not be higher than 20.");
                        if (log.IsErrorEnabled) log.Error(exception);
                        return View("Error", exception);
                    }

                    int seminarID = int.Parse(RouteData.Values["seminarID"].ToString());
                    testResult.Seminar = repository.GetSeminarByID(seminarID);
                    repository.Add(testResult);
                    repository.Save();

                    if (log.IsDebugEnabled) log.Debug("Leaving TestResult creation (POST)...");
                    return RedirectToAction("Index", new { seminarID = seminarID });
                }
                catch
                {
                    //ModelState.AddRuleViolations(TestResult.GetRuleViolations());
                }
            }


            if (log.IsDebugEnabled)
            {
                //TODO: completar Create_TestResult
            } 
            
            return View(testResult);
        }

        #endregion

        #region Edit

        //
        // GET: /TestResult/Edit/5

        public ActionResult Edit(int id)
        {

            TestResult testResult = repository.Get(id);
            if (testResult == null)
                return View("NotFound");

            return View(testResult);
        }

        //
        // POST: /TestResult/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, int seminarid, FormCollection collection)
        {
            TestResult testResult = repository.Get(id);

            try
            {
                UpdateModel(testResult);

                if (testResult.TestResultTotalAnswers > 20)
                {
                    ApplicationException exception = new ApplicationException(string.Format("The total number of answers cannot exceed 20 (it's {0})", testResult.TestResultTotalAnswers));
                    if (log.IsErrorEnabled) log.Error(exception);
                    return View("Error", exception);
                }
                
                repository.Save();

                return RedirectToAction("Index", "TestResult", new { seminarID = seminarid });
            }
            catch
            {
                return View(testResult);
            }
        }

        #endregion

        #region Delete

        //
        // GET: /TestResult/Delete/5

        /// <summary>
        /// Returns the view associated with a given entity to be deleted
        /// </summary>
        /// <param name="id">The id of the existing entity</param>
        /// <returns>Delete view</returns>
        [Authorize(Roles = "Administrator,Reporter")]
        public ActionResult Delete(int id)
        {
            throw new NotImplementedException();

            if (log.IsDebugEnabled) log.DebugFormat("Entering TestResult with id {0} delete (GET)...", id);
            TestResult testResult = repository.Get(id);

            if (testResult == null)
            {
                if (log.IsErrorEnabled) log.ErrorFormat("TestResult with id={0} not found", id);
                return View("NotFound");
            }

            if (log.IsDebugEnabled) log.DebugFormat("Leaving TestResult with id {0} delete (GET)...", id);
            return View(testResult);
        }

        //
        // POST: /TestResult/Delete/5

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        /// <param name="id">The id of the existing entity</param>
        /// <param name="confirmButton">The confirm button.</param>
        /// <returns>Deleted view</returns>
        [HttpPost]
        [Authorize(Roles = "Administrator,Reporter")]
        public ActionResult Delete(int id, string confirmButton)
        {
            throw new NotImplementedException();

            if (log.IsDebugEnabled) log.DebugFormat("Entering TestResult with id {0} delete (POST)...", id);
            TestResult testResult = repository.Get(id);
            int seminarID = testResult.Seminar.SeminarID;

            if (testResult == null)
            {
                if (log.IsErrorEnabled) log.ErrorFormat("TestResult with id={0} not found", id);
                return View("NotFound");
            }

            repository.Delete(testResult);
            repository.Save();

            if (log.IsDebugEnabled) log.DebugFormat("Leaving TestResult with id {0} delete (POST)...", id);
            return RedirectToAction("Index", "TestResult", new { seminarID = seminarID });
        }

        #endregion

        //
        // GET: /TestResult/Export/5

        /// <summary>
        /// Returns the view associated with a given entity to be deleted
        /// </summary>
        /// <param name="id">The id of the existing entity</param>
        /// <returns>Delete view</returns>
        [Authorize(Roles = "Administrator,Reporter")]
        public ActionResult Export(int id)
        {
            var seminar = repository.GetSeminarByID(id);

            List<ExcelSheetInformation> sheets = new List<ExcelSheetInformation>();
            List<ExcelCellChange> excelFistPageChanges = new List<ExcelCellChange>();


            int testAnsweredPerSeminar = seminar.TestResults.Count;
            int testCorrectPerSeminar = seminar.TestResults.Sum(ts => ts.TestResultCorrectAnswers);
            int testIncorrectPerSeminar = seminar.TestResults.Sum(ts => ts.TestResultIncorrectAnswers);
            int testNoAnsweredPerSeminar = seminar.TestResults.Sum(ts => ts.TestResultNotAnswered);

            excelFistPageChanges.AddRange(new List<ExcelCellChange>
                        {
                        new ExcelCellChange { Row = 2, Column = 2, Value = seminar.TargetArea.Program.ProgramName },
                        new ExcelCellChange { Row = 3, Column = 2, Value = "TEST RESULTS - " + seminar.FriendlyTitle },
                        new ExcelCellChange { Row = 5, Column = 3, Value = testAnsweredPerSeminar },
                        new ExcelCellChange { Row = 7, Column = 3, Value = testCorrectPerSeminar },
                        new ExcelCellChange { Row = 8, Column = 3, Value = testIncorrectPerSeminar },
                        new ExcelCellChange { Row = 9, Column = 3, Value = testNoAnsweredPerSeminar },
                        });

            ExcelSheetInformation sheet = new ExcelSheetInformation() { Name = "Seminar Test Results", Changes = excelFistPageChanges };
            sheets.Add(sheet);

        
            string temporaryFileName = Server.MapPath(@"~/temp/" + Guid.NewGuid() + ".xlsx");

            if (log.IsDebugEnabled) log.DebugFormat("Leaving Program with id {0} ta...", id);

            return this.Excel("EOD_Single_Seminar_Tests_Results.xlsx", temporaryFileName, Server.MapPath(@"~/templates/EOD_Single_Seminar_Tests_Results.xlsx"), "EODs Test Results SUMMARY", sheets.AsQueryable());

        }

    }
}
